# coding: UTF-8
'''
Created on 2011/04/21

@author: yang_wanjun
'''
import datetime
#from django.db import models
from django.db.models import permalink
from django.db.models import Max
from django.conf import settings
from django.contrib.auth.admin import User
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import gettext_lazy as _

from senbzblog.tags.models import Tag
from senbzblog.blog.managers import *
from senbzblog.comments.models import Comment

GENDER = (
    (1, _('male')),
    (2, _('female')),
)
DISPLAY_COUNT = (
    (5, 5),
    (10, 10),
    (15, 15),
    (20, 20),
)

def get_upload_to(instance, filename):
    return settings.MEDIA_ROOT + "/" + instance.user.username + "/portrait.jpeg"
    
class UserProfile(models.Model):
    user = models.OneToOneField(User)
    nickname = models.CharField(_('nick name'), max_length=30, blank=True, null=True)
    image_url = models.ImageField(_('picture'), max_length=256, upload_to=get_upload_to, blank=True, null=True)
    gender = models.IntegerField(_('gender'), choices=GENDER, max_length=1, blank=True, null=True)
    telephone = models.CharField(_('telephone'), max_length=20, blank=True, null=True)
    qq = models.CharField(_('QQ'), max_length=20, blank=True, null=True)
    msn = models.EmailField(_('MSN'), max_length=30, blank=True, null=True)
    birthday = models.DateField(_('birthday'), blank=True, null=True)
    birth_town = models.CharField(_('birth town'), max_length=30, blank=True, null=True)
    live_town = models.CharField(_('live town'), max_length=30, blank=True, null=True)
    description = models.CharField(_('user description'), max_length=255, null=True, blank=True)
    
    @permalink
    def get_admin_save_profile_url(self):
        return ('admin_save_profile', None, {'username':self.user.username})
    
class BlogInfo(models.Model):
    id = models.IntegerField(primary_key=True, blank=True, editable=False)
    user = models.OneToOneField(User)
    title = models.CharField(_('title'), max_length=30)
    description = models.CharField(_('description'), max_length=256, null=True, blank=True)
    notice = models.CharField(_('notice'), max_length=256, null=True, blank=True)
    theme = models.CharField(_('theme'), max_length=30, default='default')    #主题名称
    display_count = models.IntegerField(_('display count'), default=10, choices=DISPLAY_COUNT) #每页显示的文章数
    allow_comment = models.BooleanField(_('allow comment'), default=True)   #是否允许评论
    
    class Meta:
        db_table = 'blog_info'
        
    def get_recent_articles(self):
        """最近添加的文章"""
        return Article.objects.filter(blog=self.id)[:5]
    def get_ranking_articles(self):
        '''获取最多浏览的文章'''
        return Article.objects.filter(blog=self.id).order_by('-browse')[:5]
    
    def get_article_categories(self):
        """所有的博客分类"""
        return Category.objects.filter(blog=self.id)
    def get_root_categories(self):
        """所有的博客分类"""
        return Category.objects.filter(blog=self.id, parent=None)
    
    def get_links(self):
        return Link.objects.filter(blog=self)
    
    def save(self):
        if self.id == None:
            id_max = BlogInfo.objects.aggregate(Max('id'))['blog_id__max']
            if id_max == None:
                self.id = 1
            else:
                self.id = id_max + 1
        super(BlogInfo, self).save()
    
    def __unicode__(self):
        return self.title + '(' + self.user.username + ')'
    
    @permalink
    def get_absolute_url(self):
        return ('blog_home', None, {'username':self.user.username})
    
    @permalink
    def get_admin_show_categories_url(self):
        return ('admin_show_categories', None, {'username':self.user.username})
    
    @permalink
    def get_admin_add_category_url(self):
        return ('admin_save_category', None, {'username':self.user.username})
    
    @permalink
    def get_admin_delete_category_url(self):
        return ('admin_delete_category', None, {'username': self.user.username})
    @permalink
    def get_admin_show_pages_url(self):
        return ('admin_show_pages', None, {'username':self.user.username})
    @permalink
    def get_admin_show_articles_url(self):
        return ('admin_show_articles', None, {'username':self.user.username})
    @permalink
    def get_admin_show_articles_published_url(self):
        return ('admin_show_articles_published', None, {'username':self.user.username})
    @permalink
    def get_admin_show_articles_unpublished_url(self):
        return ('admin_show_articles_unpublished', None, {'username':self.user.username})
    
    @permalink
    def get_admin_show_article_url(self):
        return ('admin_show_article', None, {'username':self.user.username})
    @permalink
    def get_admin_quick_post_url(self):
        return ('admin_quick_post', None, {'username':self.user.username})
    @permalink
    def get_admin_save_article_url(self):
        return ('admin_save_article', None, {'username':self.user.username})
        
    @permalink
    def get_admin_delete_articles_url(self):
        return ('admin_delete_articles', None, {'username':self.user.username})
    @permalink
    def get_admin_comments_url(self):
        return ('admin_comments', None, {'username':self.user.username})
    @permalink
    def get_admin_comments_span_url(self):
        return ('admin_comments_span', None, {'username':self.user.username})
    @permalink
    def get_admin_links_url(self):
        return ('admin_links', None, {'username':self.user.username})
    @permalink
    def get_admin_add_link_url(self):
        return ('admin_add_link', None, {'username':self.user.username})
    @permalink
    def get_admin_delete_links_url(self):
        return ('admin_delete_links', None, {'username':self.user.username})
    @permalink
    def get_admin_user_url(self):
        return ('admin_user', None, {'username':self.user.username})
    @permalink
    def get_admin_profile_url(self):
        return ('admin_profile', None, {'username':self.user.username})
    @permalink
    def get_admin_change_password_url(self):
        return ('admin_change_password', None, {'username':self.user.username})
    @permalink
    def get_admin_settings_url(self):
        return ('admin_settings', None, {'username':self.user.username})
    @permalink
    def get_admin_settings_save_url(self):
        return ('admin_settings_save', None, {'username':self.user.username})
    
    @permalink
    def get_show_about_url(self):
        return ('show_about', None, {'username':self.user.username})
    @permalink
    def get_show_contact_url(self):
        return ('show_contact', None, {'username':self.user.username})
    
    @permalink
    def get_show_articles_url(self):
        return ('show_articles', None, {'username':self.user.username})
    
class Category(models.Model):
    id = models.IntegerField(primary_key=True, blank=True)
    title = models.CharField(_('title'), max_length=50)
    slug = models.SlugField(_('alias'), max_length=50)
    description = models.CharField(_('description'), max_length=256, blank=True, null=True)
    type = models.IntegerField(_('type'), default=1)
    order = models.PositiveIntegerField(_('display order'))
    parent = models.ForeignKey('Category', null=True, blank=True, related_name='children')
    blog = models.ForeignKey(BlogInfo)
    created_date = models.DateTimeField(_('created date'), default=datetime.datetime.now(), editable=False)
    
    class Meta:
        ordering = ['order']
        unique_together = (('blog', 'slug'),)
    
    def save(self, force_insert=False, force_update=False):
        if self.id == None:
            force_insert = True
            id_max = Category.objects.aggregate(Max('id'))['id__max']
            if id_max == None:
                self.id = 1
            else:
                self.id = id_max + 1
        else:
            force_update = True
        super(Category, self).save(force_insert, force_update)
    
    def __unicode__(self):
        return self.title
    
    def has_parent(self):
        '''判断是否有父目录'''
        if self.parent:
            return True
        else:
            return False
    def has_children(self):
        '''判断是否有子目录'''
        if self.children.all().count() > 0:
            return True
        else:
            return False
    def get_root_category(self):
        '''获取父目录'''
        if self.parent:
            return self.parent.get_root_category()
        else:
            return self.id
    
    def get_article_count(self):
        return Article.objects.filter(category=self.id).count()
    
    @permalink
    def get_show_category_url(self):
        return ('show_category', None, {'username':self.blog.user.username, 'slug':self.slug})
    
    @permalink
    def get_admin_show_category_url(self):
        return ('admin_show_category', None, {'username':self.blog.user.username, 'slug': self.slug})

class Article(models.Model):
    id = models.IntegerField(primary_key=True, blank=True)
    title = models.CharField(_('title'), max_length=50)
    slug = models.SlugField(_('alias'), max_length=50,
        help_text=_('Show in the URL which contain only letter, number or underline to find the article.'))
    blog = models.ForeignKey(BlogInfo)
    contents = models.TextField(_('contents'))
    summary = models.TextField(_('summary'), blank=True, null=True,
        help_text=_('Show in article list to describe the article.'))
    is_published = models.BooleanField(_('is published', default=False))
    allow_comment = models.BooleanField(_('allow comment'), default=True)
    created_date = models.DateTimeField(_('created date'), default=datetime.datetime.now(),
        auto_now_add=True, editable=False)
    updated_date = models.DateTimeField(_('updated date'), default=datetime.datetime.now(),
                                        auto_now_add=True, editable=False)
    category = models.ForeignKey(Category, verbose_name=_('category'))
    tags = models.CharField(_('tags'), max_length=255, blank=True, null=True,
        help_text=_('Use half-width comma to splits tags'))
    browse = models.IntegerField(default=0, null=True, blank=True)

    class Meta:
        ordering = ['-created_date']
        unique_together = (('blog', 'slug'),)
    
    admin_objects = models.Manager()
    objects = ViewableArticleManager()
    
    def get_next(self):
        '''取得下一条数据'''
        next = Article.objects.filter(created_date__gt=self.created_date).order_by('created_date')
        if len(next) > 0:
            return next[0]
        else:
            return None
        
    def get_prev(self):
        '''取得上一条数据'''
        prev = Article.objects.filter(created_date__lt=self.created_date).order_by('-created_date')
        if len(prev) > 0:
            return prev[0]
        else:
            return None
        
    def get_published(self):
        '''获取已经发布的所有文章'''
        return Article.objects.filter(blog=self.blog, is_published=True)
    
    def get_unpublished(self):
        '''获取所有未发布的文章'''
        return Article.objects.filter(blog=self.blog, is_published=False)
    
    def get_comments_count(self):
        ctype = ContentType.objects.get_for_model(Article)
        return Comment.objects.filter(content_type=ctype, object_pk=self.pk).count()
    
    def save(self):
        if self.id == None:
            id_max = Article.objects.aggregate(Max('id'))['id__max']
            if id_max == None:
                self.id = 1
            else:
                self.id = id_max + 1
        super(Article, self).save()
        Tag.objects.update_tags(self, self.tags)
    
    def __unicode__(self):
        return self.title
    
    @permalink
    def get_absolute_url(self):
        return ('show_article', None , {'slug':self.slug, 'username':self.blog.user.username})
    @permalink
    def get_post_comment_url(self):
        return ('post_comment', None , {'slug':self.slug, 'username':self.blog.user.username})
    
    @permalink
    def get_admin_edit_article_url(self):
        return ('admin_edit_article', None , {'slug':self.slug, 'username':self.blog.user.username})
    @permalink
    def get_admin_delete_article_url(self):
        return ('admin_delete_article', None , {'id':self.id, 'username':self.blog.user.username})

class Link(models.Model):
    id = models.IntegerField(primary_key=True, blank=True)
    link_url = models.URLField(_('URL'))
    title = models.CharField(_('title'), max_length=30)
    description = models.CharField(_('description'), max_length=50, blank=True, null=True)
    created_date = models.DateTimeField(_('created date'), auto_now_add=True, editable=False)
    blog = models.ForeignKey(BlogInfo, editable=False)
    
    def __unicode__(self):
        return self.title
    
    def save(self, force_insert=False, force_update=False):
        if not self.id:
            force_insert = True
            id_max = Link.objects.aggregate(Max('id'))['id__max']
            if id_max == None:
                self.id = 1
            else:
                self.id = id_max + 1
        else:
            force_update = True
        super(Link, self).save(force_insert, force_update)

    @permalink
    def get_admin_edit_link_url(self):
        return ('admin_edit_link', None, {'username':self.blog.user.username, 'id':self.id})

class Page(models.Model):
    id = models.IntegerField(primary_key=True, blank=True)
    title = models.CharField(_('title'), max_length=50)
    slug = models.SlugField(_('alias'), max_length=50,
        help_text=_('Show in the URL which contain only letter, number or underline to find the article.'))
    blog = models.ForeignKey(BlogInfo)
    order = models.PositiveIntegerField(_('display order'))
    contents = models.TextField(_('page content'))
    is_published = models.BooleanField(_('is published', default=False))
    allow_comment = models.BooleanField(_('allow comment'), default=True)
    created_date = models.DateTimeField(_('created date'), default=datetime.datetime.now(), editable=False)
    updated_date = models.DateTimeField(_('updated date'), auto_now_add=True, editable=False)

    class Meta():
        ordering = ['order']
    
    admin_objects = models.Manager()
    objects = ViewablePageManager()
    
    def save(self):
        if self.id == None:
            id_max = Page.admin_objects.aggregate(Max('id'))['id__max']
            if id_max == None:
                self.id = 1
            else:
                self.id = id_max + 1
        super(Page, self).save()
    
    @permalink
    def get_post_comment_url(self):
        return ('post_comment', None , {'slug':self.slug, 'username':self.blog.user.username})
    
    @permalink
    def get_admin_edit_page_url(self):
        return ('admin_edit_page', None , {'slug':self.slug, 'username':self.blog.user.username}) 
    @permalink
    def get_admin_delete_page_url(self):
        return ('admin_delete_page', None , {'slug':self.slug, 'username':self.blog.user.username}) 
    @permalink
    def get_absolute_url(self):
        return ('show_page', None , {'slug':self.slug, 'username':self.blog.user.username}) 

class History(models.Model):
    article = models.ForeignKey(Article, related_name='history')
    date = models.DateTimeField(auto_now_add=True, editable=False)
    ip_address = models.IPAddressField(editable=False)
    user = models.ForeignKey(User, null=True, blank=True, editable=False)
    session_id = models.CharField(max_length=50, editable=False)

    @staticmethod
    def add_history(article, ip_address, user, session_id):
        '''添加文章的浏览记录'''
        if article.history.filter(session_id=session_id).count() <= 0:
            if not isinstance(user, User):
                user = None
            history = History(article=article, ip_address=ip_address, user=user, session_id=session_id)
            try:
                history.save()
                article.browse = article.history.count()
                article.save()
            except:
                pass

